package com.neusoft.databus.policy.utils;

import java.util.Map;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.apache.commons.jexl3.JexlBuilder;
import org.apache.commons.jexl3.JexlContext;
import org.apache.commons.jexl3.JexlEngine;
import org.apache.commons.jexl3.JexlException;

import lombok.extern.slf4j.Slf4j;

/**
 * jexl3公式解析器
 *
 * @author naxiang
 */
@Slf4j
public class ExpressionCalculator {

    public static final ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");

    public static final JexlEngine jexl = new JexlBuilder().create();

    public static Boolean getCalculatorResult(String expression, Map<String, Object> variableValueMap)
            throws ScriptException {
        Boolean result = false;
        if ((variableValueMap != null) && !variableValueMap.isEmpty()) {
            for (final Map.Entry<String, Object> entry : variableValueMap.entrySet()) {
                expression = expression.replaceAll(entry.getKey(), entry.getValue().toString());
            }
        }
        ExpressionCalculator.log.debug("表达式:{}", expression);
        try {
            result = (Boolean) ExpressionCalculator.engine.eval(expression);
        } catch (final ScriptException e) {
            ExpressionCalculator.log.error("公式{}不合法！", expression);
            throw e;
        } finally {
            variableValueMap = null;
            expression = null;
        }
        return result;
    }

    public static Boolean getJexlCalculatorResult(String expression, final JexlContext jexlContext)
            throws JexlException {
        Boolean result = false;
        ExpressionCalculator.log.debug("解析表达式:{}", expression);
        try {
            result = (Boolean) ExpressionCalculator.jexl.createExpression(expression).evaluate(jexlContext);
        } catch (final JexlException e) {
            ExpressionCalculator.log.error("公式{}不合法！", expression);
            throw e;
        } finally {
            expression = null;
        }
        return result;
    }
}
